﻿#region Copyrights

/*
    - - - - - - - - - - - - - - - - - - - - - - -
    Nome do Arquivo : DAOBase.cs
    - - - - - - - - - - - - - - - - - - - - - - -

    Sistema				    :  	LLS.Core
    Modulo				    :  	LLS.DataAccess.Core
    Autor				    :	Leonardo L. de Siqueira
    Data					:	27/02/2012
    Descrição  				:	Classe abstrata base para todos os objetos de acesso a dados.
    
*/

#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LLS.DataModel.Core;
using System.Data;

namespace LLS.DataAccess.Core
{
    /// <summary>
    /// Classe abstrata base para todos os objetos de acesso a dados.
    /// </summary>
    /// <typeparam name="U">Objeto com herança do tipo DMOBase</typeparam>
    public abstract class DAOBase<U>
        where U : DMOBase
    {
        #region Constants

        /// <summary>
        /// Constante com o comando SQL utilizado para salvar dados no banco de dados
        /// </summary>
        internal const string _sQLCommandToSave = "INSERT INTO {0} ({1}) VALUES ({2}); SELECT SCOPE_IDENTITY()";

        /// <summary>
        /// Constante com o comando SQL utilizado para alterar dados no banco de dados
        /// </summary>
        internal const string _sQLCommandToUpdate = "UPDATE {0} SET {1} WHERE {2}";

        /// <summary>
        /// Constante com o comando SQL para excluir dados do banco de dados
        /// </summary>
        internal const string _sQLCommandToDelete = "DELETE FROM {0} {1}";

        /// <summary>
        /// Constante com o comando SQL para carregar dados do banco de dados
        /// </summary>
        internal const string _sQLCommandToLoad = "SELECT {0} FROM {1} {2}";

        /// <summary>
        /// Constante com o comando SQL para carregar dados do banco de dados de modo paginado
        /// </summary>
        internal const string _sQLCommandToLoadPagedData = "SELECT TOP {0} {1} FROM {2} WHERE {3} NOT IN (SELECT TOP {4} {5}.{3} FROM {2} {5} {6}) {7}";

        /// <summary>
        /// Constante com o comando SQL para contar dados do banco de dados
        /// </summary>
        internal const string _sQLCommandToCount = "SELECT COUNT({0}) FROM {1} {2}";

        #endregion

        #region Fields

        System.Reflection.ConstructorInfo _ci = null;
        private U _dataModel = null;
        private Type _type = typeof(U);

        #endregion

        #region Public Methods

        /// <summary>
        /// Método construtor
        /// </summary>
        public DAOBase()
        {
            _ci = _type.GetConstructor(System.Type.EmptyTypes);
            _dataModel = (U)_ci.Invoke(null);
        }

        /// <summary>
        /// Persiste um novo registro em uma tabela do banco de dados
        /// </summary>
        /// <param name="dataModel">Modelo de dados</param>        
        public virtual void Save(U dataModel)
        {
            Save(dataModel, null);
        }

        /// <summary>
        /// Carrega um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a carga</param>        
        /// <returns>Lista de modelo de dados carregados</returns>
        public virtual List<U> Load(Filter<U> filter)
        {
            return Load(filter, null);
        }

        /// <summary>
        /// Carrega um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a carga</param>
        /// <param name="startRowIndex">posição inicial na base de dados para início da carga</param>
        /// <param name="maximumRows">Quantidade máxima de registros permitidos para retorno</param>        
        /// <returns>Lista de modelo de dados carregados</returns>
        public virtual List<U> Load(Filter<U> filter, Int64 startRowIndex, Int64 maximumRows)
        {
            return Load(filter, startRowIndex, maximumRows, null);
        }

        /// <summary>
        /// Carrega todos os registros de uma tabela do banco de dados
        /// </summary>        
        /// <returns>Lista de modelo de dados carregados</returns>
        public virtual List<U> LoadAll()
        {
            return LoadAll(null);
        }

        /// <summary>
        /// Atualiza um registro já existente em uma tabela do banco de dados
        /// </summary>
        /// <param name="dataModel">Modelo de dados</param>
        public virtual void Update(U dataModel)
        {
            Update(dataModel, null);
        }

        /// <summary>
        /// Exclui um ou mais registros em uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a exclusão</param>        
        public virtual void Delete(Filter<U> filter)
        {
            Delete(filter, null);
        }

        /// <summary>
        /// Exclui todos os registros em uma tabela do banco de dados
        /// </summary>
        public virtual void DeleteAll()
        {
            DeleteAll(null);
        }

        /// <summary>
        /// Conta um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a contagem</param>
        /// <returns>Quantidade contabilizada de registros</returns>
        public virtual Int32 Count(Filter<U> filter)
        {
            return Count(filter, null);
        }

        /// <summary>
        /// Conta todos os registros de uma tabela do banco de dados
        /// </summary>
        /// <returns>Quantidade contabilizada de registros</returns>
        public virtual Int32 CountAll()
        {
            return CountAll(null);
        }

        #endregion

        #region Transational Public Methods

        /// <summary>
        /// Persiste um novo registro em uma tabela do banco de dados
        /// </summary>
        /// <param name="dataModel">Modelo de dados</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        public virtual void Save(U dataModel, DAOHelper dAOHelper)
        {
            if (dataModel == null) throw new ArgumentNullException("dataModel");

            object ret = null;
            bool isTransaction = false;
            string primaryKey = string.Empty;
            string commandText = string.Empty;
            DAOHelper.Parameter[] parameters = null;

            if (dAOHelper == null)
            {
                isTransaction = false;
                dAOHelper = new DAOHelper();
            }
            else
                isTransaction = true;

            //Resgata as informações das propriedades do modelo de dados U            
            DMOBase.PropertiesInformation propertiesInformation = dataModel.GetPropertiesInformation();

            //Avalia se todos os campos não nulos estão preenchidos
            foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
            {
                if ((propertyInformation.ColumnAttribute.NotNull) && (propertyInformation.PropertyValue == DBNull.Value))
                    throw new NoNullAllowedException(string.Concat("The ", propertyInformation.ColumnAttribute.Name, " field of ", dataModel.GetTableName(), " table can not be null."));
            }

            //Cria os comandos para execução
            CreateCommandToSave(dataModel, propertiesInformation, out commandText, out parameters, out primaryKey);

            if (!isTransaction)
                ret = dAOHelper.ExecuteScalar(System.Data.CommandType.Text, commandText, parameters);
            else
                ret = dAOHelper.ExecuteScalar(isTransaction, System.Data.CommandType.Text, commandText, parameters);

            if (ret != null)
                dataModel.SetPropertyValue(primaryKey, ret);
        }

        /// <summary>
        /// Carrega um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a carga</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        /// <returns>Lista de modelo de dados carregados</returns>
        public virtual List<U> Load(Filter<U> filter, DAOHelper dAOHelper)
        {
            bool isTransaction = false;
            List<U> ret = new List<U>();
            string commandText = string.Empty;
            DAOHelper.Parameter[] parameters = null;
            System.Data.Common.DbDataReader dataReader = null;

            if (dAOHelper == null)
            {
                isTransaction = false;
                dAOHelper = new DAOHelper();
            }
            else
                isTransaction = true;

            //Resgata as informações das propriedades do modelo de dados U            
            DMOBase.PropertiesInformation propertiesInformation = _dataModel.GetPropertiesInformation();

            //Cria os comandos para execução
            CreateCommandToLoad(filter, propertiesInformation, out commandText, out parameters);

            if (!isTransaction)
                dataReader = dAOHelper.ExecuteReader(System.Data.CommandType.Text, commandText, parameters);
            else
                dataReader = dAOHelper.ExecuteReader(isTransaction, System.Data.CommandType.Text, commandText, parameters);

            if (dataReader.HasRows)
            {
                while (dataReader.Read())
                {
                    U dataObject = (U)_ci.Invoke(null);

                    for (int i = 0; i < dataReader.FieldCount; i++)
                    {
                        if (dataReader[i] != DBNull.Value)
                            dataObject.SetPropertyValue(dataReader.GetName(i), dataReader[i]);
                    }

                    ret.Add(dataObject);
                }
            }

            dataReader.Close();

            return ret;
        }

        /// <summary>
        /// Carrega um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a carga</param>
        /// <param name="startRowIndex">posição inicial na base de dados para início da carga</param>
        /// <param name="maximumRows">Quantidade máxima de registros permitidos para retorno</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        /// <returns>Lista de modelo de dados carregados</returns>
        public virtual List<U> Load(Filter<U> filter, Int64 startRowIndex, Int64 maximumRows, DAOHelper dAOHelper)
        {
            bool isTransaction = false;
            List<U> ret = new List<U>();
            string commandText = string.Empty;
            DAOHelper.Parameter[] parameters = null;
            System.Data.Common.DbDataReader dataReader = null;

            if (dAOHelper == null)
            {
                isTransaction = false;
                dAOHelper = new DAOHelper();
            }
            else
                isTransaction = true;

            //Resgata as informações das propriedades do modelo de dados U            
            DMOBase.PropertiesInformation propertiesInformation = _dataModel.GetPropertiesInformation();

            //Cria os comandos para execução
            CreateCommandToLoad(filter, startRowIndex, maximumRows, propertiesInformation, out commandText, out parameters);

            if (!isTransaction)
                dataReader = dAOHelper.ExecuteReader(System.Data.CommandType.Text, commandText, parameters);
            else
                dataReader = dAOHelper.ExecuteReader(isTransaction, System.Data.CommandType.Text, commandText, parameters);

            if (dataReader.HasRows)
            {
                while (dataReader.Read())
                {
                    U dataObject = (U)_ci.Invoke(null);

                    for (int i = 0; i < dataReader.FieldCount; i++)
                    {
                        if (dataReader[i] != DBNull.Value)
                            dataObject.SetPropertyValue(dataReader.GetName(i), dataReader[i]);
                    }

                    ret.Add(dataObject);
                }
            }

            dataReader.Close();

            return ret;
        }

        /// <summary>
        /// Carrega todos os registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        /// <returns>Lista de modelo de dados carregados</returns>
        public virtual List<U> LoadAll(DAOHelper dAOHelper)
        {
            return Load(null, dAOHelper);
        }

        /// <summary>
        /// Atualiza um registro já existente em uma tabela do banco de dados
        /// </summary>
        /// <param name="dataModel">Modelo de dados</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        public virtual void Update(U dataModel, DAOHelper dAOHelper)
        {
            if (dataModel == null) throw new ArgumentNullException("dataModel");

            bool isTransaction = false;
            string commandText = string.Empty;
            DAOHelper.Parameter[] paramters = null;

            if (dAOHelper == null)
            {
                isTransaction = false;
                dAOHelper = new DAOHelper();
            }
            else
                isTransaction = true;

            //Resgata as informações das propriedades do modelo de dados U            
            DMOBase.PropertiesInformation propertiesInformation = dataModel.GetPropertiesInformation();

            //Avalia se todos os campos não nulos estão preenchidos
            foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
            {
                if ((propertyInformation.ColumnAttribute.NotNull) && (propertyInformation.PropertyValue == DBNull.Value))
                    throw new NoNullAllowedException(string.Concat("The ", propertyInformation.ColumnAttribute.Name, " field of ", dataModel.GetTableName(), " table can not be null."));
            }

            //Cria os comandos para execução
            CreateCommandToUpdate(dataModel, propertiesInformation, out commandText, out paramters);

            if (!isTransaction)
                dAOHelper.ExecuteNonQuery(System.Data.CommandType.Text, commandText, paramters);
            else
                dAOHelper.ExecuteNonQuery(isTransaction, System.Data.CommandType.Text, commandText, paramters);
        }

        /// <summary>
        /// Exclui um ou mais registros em uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a exclusão</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        public virtual void Delete(Filter<U> filter, DAOHelper dAOHelper)
        {
            bool isTransaction = false;
            string commandText = string.Empty;
            DAOHelper.Parameter[] parameters = null;

            if (dAOHelper == null)
            {
                isTransaction = false;
                dAOHelper = new DAOHelper();
            }
            else
                isTransaction = true;

            //Cria os comandos para execução
            CreateCommandToDelete(filter, out commandText, out parameters);

            if (!isTransaction)
                dAOHelper.ExecuteNonQuery(System.Data.CommandType.Text, commandText, parameters);
            else
                dAOHelper.ExecuteNonQuery(isTransaction, System.Data.CommandType.Text, commandText, parameters);
        }

        /// <summary>
        /// Exclui todos os registros em uma tabela do banco de dados
        /// </summary>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        public virtual void DeleteAll(DAOHelper dAOHelper)
        {
            Delete(null, dAOHelper);
        }

        /// <summary>
        /// Conta um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a contagem</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        /// <returns>Quantidade contabilizada de registros</returns>
        public virtual Int32 Count(Filter<U> filter, DAOHelper dAOHelper)
        {
            object ret = null;
            bool isTransaction = false;
            string commandText = string.Empty;
            DAOHelper.Parameter[] parameters = null;

            if (dAOHelper == null)
            {
                isTransaction = false;
                dAOHelper = new DAOHelper();
            }
            else
                isTransaction = true;

            //Cria os comandos para execução
            CreateCommandToCount(filter, out commandText, out parameters);

            if (!isTransaction)
                ret = dAOHelper.ExecuteScalar(System.Data.CommandType.Text, commandText, parameters);
            else
                ret = dAOHelper.ExecuteScalar(isTransaction, System.Data.CommandType.Text, commandText, parameters);

            if (ret != null)
                return Convert.ToInt32(ret);
            else
                return 0;
        }

        /// <summary>
        /// Conta todos os registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        /// <returns>Quantidade contabilizada de registros</returns>
        public virtual Int32 CountAll(DAOHelper dAOHelper)
        {
            return Count(null, dAOHelper);
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Método para criação do comando e seus parâmetros para execução do método Save
        /// </summary>
        /// <param name="dataModel">Modelo de dados</param>
        /// <param name="propertiesInformation">Lista com as informações das propriedades do modelo de dados a ser salvo</param>
        /// <param name="commandText">Comando de execução SQL (output)</param>        
        /// <param name="parameters">Array de objetos do tipo DAOHelper.Parameter (output)</param>
        /// <param name="primaryKey">Nome do campo de chave primária</param>
        internal void CreateCommandToSave(U dataModel, DMOBase.PropertiesInformation propertiesInformation, out string commandText, out DAOHelper.Parameter[] parameters, out string primaryKey)
        {
            parameters = null;
            commandText = string.Empty;
            primaryKey = string.Empty;
            List<string> fields = new List<string>();
            List<string> sQLParameters = new List<string>();
            string tableName = dataModel.GetTableName();
            List<DAOHelper.Parameter> parameterList = new List<DAOHelper.Parameter>();

            //Resgata os campos usados para a inclusão
            foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
            {
                if (!propertyInformation.ColumnAttribute.PrimaryKey)
                {
                    fields.Add(propertyInformation.ColumnAttribute.Name);
                    string parameterName = string.Concat("@", propertyInformation.ColumnAttribute.Name);
                    sQLParameters.Add(parameterName);

                    DAOHelper.Parameter parameter = new DAOHelper.Parameter();
                    parameter.Name = parameterName;
                    parameter.Type = propertyInformation.ColumnAttribute.Type;
                    parameter.Size = propertyInformation.ColumnAttribute.Size;
                    parameter.Value = propertyInformation.PropertyValue;
                    parameterList.Add(parameter);
                }
                else
                    primaryKey = propertyInformation.ColumnAttribute.Name;
            }

            commandText = string.Format(_sQLCommandToSave, tableName, string.Join(",", fields), string.Join(",", sQLParameters));
            parameters = parameterList.ToArray();
        }

        /// <summary>
        /// Método para criação do comando e seus parâmetros para execução do método Load
        /// </summary>
        /// <param name="filter">Objeto de filtro para a carga</param>
        /// <param name="propertiesInformation">Lista com as informações das propriedades do modelo de dados a ser salvo</param>
        /// <param name="commandText">Comando de execução SQL (output)</param>        
        /// <param name="parameters">Array de objetos do tipo DAOHelper.Parameter (output)</param>
        internal void CreateCommandToLoad(Filter<U> filter, DMOBase.PropertiesInformation propertiesInformation, out string commandText, out DAOHelper.Parameter[] parameters)
        {
            parameters = null;
            string sQLFilter = null;
            commandText = string.Empty;
            string tableName = string.Empty;
            List<string> fields = new List<string>();
            List<DAOHelper.Parameter> parameterList = new List<DAOHelper.Parameter>();

            //Resgata o nome da tabela
            tableName = _dataModel.GetTableName();

            //Resgata os campos usados na seleção
            foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
            {
                fields.Add(propertyInformation.ColumnAttribute.Name);
            }

            if ((filter != null) && (filter.Parameters != null))
            {
                //Resgata o filtro em formato SQL
                sQLFilter = filter.ToString();

                foreach (FilterParameter parameter in filter.Parameters)
                {
                    DAOHelper.Parameter sQLParameter = new DAOHelper.Parameter();
                    sQLParameter.Name = parameter.Name;
                    sQLParameter.Type = parameter.Type;
                    sQLParameter.Size = parameter.Size;
                    sQLParameter.Value = parameter.Value;
                    parameterList.Add(sQLParameter);
                }

                parameters = parameterList.ToArray();
            }

            commandText = string.Format(_sQLCommandToLoad, string.Join(",", fields), tableName, sQLFilter);
        }

        /// <summary>
        /// Método para criação do comando e seus parâmetros para execução do método Load
        /// </summary>
        /// <param name="filter">Objeto de filtro para a carga</param>
        /// <param name="startRowIndex">posição inicial na base de dados para início da carga</param>
        /// <param name="maximumRows">Quantidade máxima de registros permitidos para retorno</param>
        /// <param name="propertiesInformation">Lista com as informações das propriedades do modelo de dados a ser salvo</param>
        /// <param name="commandText">Comando de execução SQL (output)</param>        
        /// <param name="parameters">Array de objetos do tipo DAOHelper.Parameter (output)</param>
        internal void CreateCommandToLoad(Filter<U> filter, Int64 startRowIndex, Int64 maximumRows, DMOBase.PropertiesInformation propertiesInformation, out string commandText, out DAOHelper.Parameter[] parameters)
        {
            parameters = null;
            string alias = "ALS";
            string sQLFilter = null;
            string sQLFilterWithAlias = null;
            commandText = string.Empty;
            string tableName = string.Empty;
            string primaryKeyColumnName = string.Empty;
            List<string> fields = new List<string>();
            List<DAOHelper.Parameter> parameterList = new List<DAOHelper.Parameter>();

            //Resgata o nome da tabela
            tableName = _dataModel.GetTableName();

            //Resgata o nome da coluna de chave primária
            primaryKeyColumnName = _dataModel.GetPrimaryKeyColumnName();

            //Resgata os campos usados na seleção
            foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
            {
                fields.Add(propertyInformation.ColumnAttribute.Name);
            }

            if ((filter != null) && (filter.Parameters != null))
            {
                //Resgata o filtro em formato SQL
                sQLFilter = filter.ToString();
                sQLFilterWithAlias = filter.ToString(alias);

                foreach (FilterParameter parameter in filter.Parameters)
                {
                    DAOHelper.Parameter sQLParameter = new DAOHelper.Parameter();
                    sQLParameter.Name = parameter.Name;
                    sQLParameter.Type = parameter.Type;
                    sQLParameter.Size = parameter.Size;
                    sQLParameter.Value = parameter.Value;
                    parameterList.Add(sQLParameter);
                }

                parameters = parameterList.ToArray();
            }

            commandText = string.Format(_sQLCommandToLoadPagedData, maximumRows, string.Join(",", fields), tableName, primaryKeyColumnName, startRowIndex, alias, sQLFilterWithAlias,
                (sQLFilter != null) ? sQLFilter.Replace("WHERE", "AND") : sQLFilter);
        }

        /// <summary>
        /// Método para criação do comando e seus parâmetros para execução do método Update
        /// </summary>
        /// <param name="dataModel">Modelo de dados</param>
        /// <param name="propertiesInformation">Lista com as informações das propriedades do modelo de dados a serem atualizados</param>
        /// <param name="commandText">Comando de execução SQL (output)</param>        
        /// <param name="parameters">Array de objetos do tipo DAOHelper.Parameter (output)</param>
        internal void CreateCommandToUpdate(U dataModel, DMOBase.PropertiesInformation propertiesInformation, out string commandText, out DAOHelper.Parameter[] parameters)
        {
            parameters = null;
            commandText = string.Empty;
            string primaryKey = string.Empty;
            List<string> fields = new List<string>();
            string tableName = dataModel.GetTableName();
            List<DAOHelper.Parameter> parameterList = new List<DAOHelper.Parameter>();

            //Resgata os campos usados para a inclusão
            foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
            {
                string parameterName = string.Concat("@", propertyInformation.ColumnAttribute.Name);

                if (!propertyInformation.ColumnAttribute.PrimaryKey)
                    fields.Add(string.Concat(propertyInformation.ColumnAttribute.Name, " = ", parameterName));
                else
                    primaryKey = string.Concat(propertyInformation.ColumnAttribute.Name, " = ", parameterName);

                DAOHelper.Parameter parameter = new DAOHelper.Parameter();
                parameter.Name = parameterName;
                parameter.Type = propertyInformation.ColumnAttribute.Type;
                parameter.Size = propertyInformation.ColumnAttribute.Size;
                parameter.Value = propertyInformation.PropertyValue;
                parameterList.Add(parameter);
            }

            commandText = string.Format(_sQLCommandToUpdate, tableName, string.Join(",", fields), primaryKey);
            parameters = parameterList.ToArray();
        }

        /// <summary>
        /// Método para criação do comando e seus parâmetros para execução do método Delete
        /// </summary>
        /// <param name="filter">Objeto de filtro para a exclusão</param>        
        /// <param name="commandText">Comando de execução SQL (output)</param>        
        /// <param name="parameters">Array de objetos do tipo DAOHelper.Parameter (output)</param>
        internal void CreateCommandToDelete(Filter<U> filter, out string commandText, out DAOHelper.Parameter[] parameters)
        {
            parameters = null;
            string sQLFilter = null;
            commandText = string.Empty;
            string tableName = string.Empty;
            List<string> camposParaSelecao = new List<string>();
            List<DAOHelper.Parameter> parameterList = new List<DAOHelper.Parameter>();

            //Resgata o nome da tabela
            tableName = _dataModel.GetTableName();

            if ((filter != null) && (filter.Parameters != null))
            {
                //Resgata o filtro em formato SQL
                sQLFilter = filter.ToString();

                foreach (FilterParameter parameter in filter.Parameters)
                {
                    DAOHelper.Parameter sQLParameter = new DAOHelper.Parameter();
                    sQLParameter.Name = parameter.Name;
                    sQLParameter.Type = parameter.Type;
                    sQLParameter.Size = parameter.Size;
                    sQLParameter.Value = parameter.Value;
                    parameterList.Add(sQLParameter);
                }

                parameters = parameterList.ToArray();
            }

            commandText = string.Format(_sQLCommandToDelete, tableName, sQLFilter);
        }

        /// <summary>
        /// Método para criação do comando e seus parâmetros para execução do método Count
        /// </summary>
        /// <param name="filter">Objeto de filtro para a contagem</param>
        /// <param name="commandText">Comando de execução SQL (output)</param>        
        /// <param name="parameters">Array de objetos do tipo DAOHelper.Parameter (output)</param>
        internal void CreateCommandToCount(Filter<U> filter, out string commandText, out DAOHelper.Parameter[] parameters)
        {
            parameters = null;
            string sQLFilter = null;
            commandText = string.Empty;
            string tableName = string.Empty;
            string primaryKeyColumnName = string.Empty;
            List<DAOHelper.Parameter> listaDeParametros = new List<DAOHelper.Parameter>();

            //Resgata o nome da tabela
            tableName = _dataModel.GetTableName();

            //Resgata o nome da coluna de chave primária
            primaryKeyColumnName = _dataModel.GetPrimaryKeyColumnName();

            if ((filter != null) && (filter.Parameters != null))
            {
                //Resgata o filtro em formato SQL
                sQLFilter = filter.ToString();

                foreach (FilterParameter parameter in filter.Parameters)
                {
                    DAOHelper.Parameter sQLParameter = new DAOHelper.Parameter();
                    sQLParameter.Name = parameter.Name;
                    sQLParameter.Type = parameter.Type;
                    sQLParameter.Size = parameter.Size;
                    sQLParameter.Value = parameter.Value;
                    listaDeParametros.Add(sQLParameter);
                }

                parameters = listaDeParametros.ToArray();
            }

            commandText = string.Format(_sQLCommandToCount, primaryKeyColumnName, tableName, sQLFilter);
        }

        #endregion
    }
}
